/**
 * 玩家常根据爬的说话方式来判断bot的类型，为了避免被发现是同一个bot，我们应该提供丰富的说话方式
 */

import { LifeCycles } from '@/ayaka'
import { GenshinRole, genshinData, genshinRoles } from '@/modules/genshin/roleData'
import { creepReciteWord } from './creepRecite'

/**
 * 爬-原神角色映射表
 */
const creepMap = new Map<string, { role: GenshinRole; line: number; index: number }>()

/**
 * 原神台词缓存
 */
const genshinWordsCache = new Map<string, string[]>()

/**
 * 获取爬的原神角色
 */
const getGenshinRole = (creep: Creep) => {
    const role = creep.name.split('-')[1] as GenshinRole
    if (genshinData[role]) {
        return role
    } else {
        return _.sample(genshinRoles)
    }
}

/**
 * 日常状态和战斗状态
 */
type State = 'peace' | 'war'

/**
 * 随机返回一行台词
 */
const getRandomLine = (role: GenshinRole, state: State = 'peace') => {
    return _.random(0, genshinData[role][state].length - 1)
}

/**
 * 随机返回一句签名
 */
export const getRandomSign = (state: State = 'peace') => {
    const role = _.sample(genshinRoles)
    const line = getRandomLine(role, state)
    return `${genshinData[role][state][line]}\n\t ——${role}`
}

/**
 * 默认说话策略（不说话）
 */
const creepSayByDefault = () => 0

/**
 * 根据原神说话
 */
const creepSayByGenshin = (creeps: Creep[], p = 0.5) => {
    creeps.forEach((creep) => {
        if (Math.random() > p) return

        let sayInfo = creepMap.get(creep.name)
        if (!sayInfo) {
            const role = getGenshinRole(creep)
            const line = getRandomLine(role)
            const index = 0
            creepMap.set(creep.name, (sayInfo = { role, line, index }))
        }

        let words = genshinWordsCache.get(`${sayInfo.role}${sayInfo.line}`)
        if (!words) {
            words = genshinData[sayInfo.role].peace[sayInfo.line].split(/[。？…，！~——]/)
            genshinWordsCache.set(`${sayInfo.role}${sayInfo.line}`, words)
        }

        if (words[sayInfo.index]) creep.say(words[sayInfo.index], true)
        sayInfo.index++

        if (sayInfo.index >= words.length) {
            sayInfo.line = getRandomLine(sayInfo.role)
            sayInfo.index = 0
        }
    })
    if (Game.time % 1617 === 0) {
        for (const creepName of creepMap.keys()) {
            if (!Game.creeps[creepName]) {
                creepMap.delete(creepName)
            }
        }
    }
}

/**
 * 命名策略，不必考虑重名问题，因为重名会导致孵化失败，孵化任务会被清除
 */
export const creepSayStrategy = {
    default: creepSayByDefault,
    genshin: creepSayByGenshin,
    reciteWord: creepReciteWord,
}

export const creepSay: LifeCycles = {
    tickStart() {
        const strategy = Memory.meta?.creepSay?.[0] ?? 'default'
        const probability = Memory.meta?.creepSay?.[1]
        const strategyFn = creepSayStrategy[strategy] ? creepSayStrategy[strategy] : creepSayByDefault
        strategy === 'default' || strategyFn(Object.values(Game.creeps), probability)
    },
}
